Skip to content

feat: add CI/CD pipeline for Kolo Soroban smart contract - #30

Merged
Queenode merged 6 commits into
Kolo-Org:mainfrom
abimbolaalabi:feat/pipeline-integration
Jul 21, 2026
Merged

feat: add CI/CD pipeline for Kolo Soroban smart contract#30
Queenode merged 6 commits into
Kolo-Org:mainfrom
abimbolaalabi:feat/pipeline-integration

Conversation

@abimbolaalabi

@abimbolaalabi abimbolaalabi commented Jul 20, 2026

Copy link
Copy Markdown
Contributor

Implement automated GitHub Actions workflow that validates every pull request and push to main/develop.

The issue description references a Node.js/TypeScript/Prisma pipeline, but this repository is a Rust Soroban smart contract. This implementation follows the repository's actual build and validation requirements.

Key changes:

  • Create .github/workflows/ci.yml with comprehensive Rust/Soroban CI/CD
  • Remove redundant .github/workflows/rust.yml (replaced by ci.yml)

Pipeline jobs:

build-and-test (runs on every push/PR to main/develop):

  • Rust toolchain setup (rustfmt, clippy, wasm32 target)
  • Cargo dependency caching for faster builds
  • Format check: cargo fmt --all -- --check
  • Linting: cargo clippy --all-targets --all-features -- -D warnings
  • Native build: cargo build (quick compile check)
  • Tests: cargo test --verbose (all 7 unit tests)
  • WASM build: cargo build --target wasm32-unknown-unknown --release
  • Artifact upload: saves optimized .wasm for 14 days

deploy (only on push to main, after all checks pass):

  • Installs Stellar CLI (soroban v21.2.0)
  • MVP-compatible WASM build + wasm-opt optimization
  • Deploys contract to Stellar testnet

This pipeline acts as the final gatekeeper against merging broken code that could cause production outages or loss of user funds.

Closes #28

Summary by CodeRabbit

  • CI/CD
    • Revamped the pipeline into “Kolo Backend CI” with consistent Rust setup, formatting checks, stricter linting (warnings fail), native builds, verbose tests, and WebAssembly release builds.
    • Added automated WebAssembly artifact upload.
    • Implemented an automated Stellar testnet deploy that runs on pushes to main only, including wasm rebuild and optimization.
    • Limited workflow runs to main and develop for push/pull requests.

Implement automated GitHub Actions workflow that validates every
pull request and push to main/develop.

The issue description references a Node.js/TypeScript/Prisma pipeline,
but this repository is a Rust Soroban smart contract. This implementation
follows the repository's actual build and validation requirements.

Key changes:
- Create .github/workflows/ci.yml with comprehensive Rust/Soroban CI/CD
- Remove redundant .github/workflows/rust.yml (replaced by ci.yml)

Pipeline jobs:

  build-and-test (runs on every push/PR to main/develop):
  - Rust toolchain setup (rustfmt, clippy, wasm32 target)
  - Cargo dependency caching for faster builds
  - Format check: cargo fmt --all -- --check
  - Linting: cargo clippy --all-targets --all-features -- -D warnings
  - Native build: cargo build (quick compile check)
  - Tests: cargo test --verbose (all 7 unit tests)
  - WASM build: cargo build --target wasm32-unknown-unknown --release
  - Artifact upload: saves optimized .wasm for 14 days

  deploy (only on push to main, after all checks pass):
  - Installs Stellar CLI (soroban v21.2.0)
  - MVP-compatible WASM build + wasm-opt optimization
  - Deploys contract to Stellar testnet

This pipeline acts as the final gatekeeper against merging broken
code that could cause production outages or loss of user funds.
@coderabbitai

coderabbitai Bot commented Jul 20, 2026

Copy link
Copy Markdown

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • 🔍 Trigger review
📝 Walkthrough

Walkthrough

The Rust workflow validates formatting, linting, builds, tests, and WebAssembly artifacts for main and develop, then conditionally optimizes and deploys the contract to Stellar testnet after successful main pushes.

Changes

Rust Soroban CI/CD

Layer / File(s) Summary
Validation and WASM artifact
.github/workflows/rust.yml
Restricts workflow triggers, configures the Rust toolchain and Cargo caching, runs formatting, Clippy, native builds, verbose tests, release WebAssembly compilation, and artifact upload.
Conditional testnet deployment
.github/workflows/rust.yml
Adds a main-push deployment job that installs stellar-cli, rebuilds and optimizes WebAssembly, and deploys to Stellar testnet with STELLAR_DEPLOYER_KEY.

Estimated code review effort: 3 (Moderate) | ~25 minutes

Sequence Diagram(s)

sequenceDiagram
  participant GitHub Actions
  participant Rust toolchain
  participant stellar-cli
  participant Stellar testnet
  GitHub Actions->>Rust toolchain: run formatting, linting, build, and tests
  Rust toolchain-->>GitHub Actions: produce release WASM
  GitHub Actions->>stellar-cli: optimize WASM and provide deployer key
  stellar-cli->>Stellar testnet: deploy optimized contract
Loading
🚥 Pre-merge checks | ✅ 5
✅ Passed checks (5 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title clearly summarizes the main change: adding a CI/CD pipeline for the Soroban smart contract.
Linked Issues check ✅ Passed The workflow satisfies #28 by adding automated PR/push checks and conditional main-branch deployment for the Rust contract.
Out of Scope Changes check ✅ Passed The changes stay within the CI/CD workflow scope and do not introduce unrelated code or configuration updates.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.
✨ Finishing Touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
.github/workflows/ci.yml (1)

1-106: 🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Add a top-level permissions block with least-privilege access.

The workflow has no permissions: block, so it inherits the default token permissions, which may be broader than necessary. This workflow only needs contents: read for checkout and artifact upload. Add an explicit block to reduce blast radius if the token is leaked.

🔒 Suggested fix
 env:
   CARGO_TERM_COLOR: always
   WORKING_DIR: contracts

+permissions:
+  contents: read
+
 jobs:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 1 - 106, Add a top-level permissions
block near the workflow metadata, granting only contents: read. Leave the
existing jobs and steps unchanged so checkout and artifact upload continue using
the minimum required token access.

Source: Linters/SAST tools

🧹 Nitpick comments (3)
.github/workflows/ci.yml (3)

90-92: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Apply RUSTFLAGS="-C target-cpu=mvp" consistently across both jobs.

The deploy job sets RUSTFLAGS="-C target-cpu=mvp" for the WASM build, but the build-and-test job (line 49) builds WASM without this flag. This means the uploaded artifact from build-and-test is built with different compiler flags than the deployed WASM. For consistency, either apply the same RUSTFLAGS in both jobs or document why they intentionally differ.

♻️ Suggested fix — add RUSTFLAGS to the build-and-test WASM step
       - name: Build WebAssembly (release)
-        run: cargo build --target wasm32-unknown-unknown --release
+        run: RUSTFLAGS="-C target-cpu=mvp" cargo build --target wasm32-unknown-unknown --release
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 90 - 92, Apply RUSTFLAGS="-C
target-cpu=mvp" to the WASM build command in the build-and-test job, matching
the existing deploy job configuration. Keep both jobs’ WASM artifacts built with
the same compiler flags.

88-96: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Replace cargo install wasm-opt with a faster installation method.

cargo install wasm-opt --locked compiles from source on every deploy run, adding significant time. Install binaryen (which provides wasm-opt) via apt instead for a pre-built binary.

⚡ Suggested fix
       - name: Build and optimize WASM
         run: |
+          sudo apt-get update && sudo apt-get install -y binaryen
           RUSTFLAGS="-C target-cpu=mvp" cargo build \
             --target wasm32-unknown-unknown \
             --release
-          cargo install wasm-opt --locked
           wasm-opt \
             target/wasm32-unknown-unknown/release/kolo_savings_group.wasm \
             -o target/wasm32-unknown-unknown/release/kolo_savings_group.optimized.wasm
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 88 - 96, In the “Build and optimize
WASM” workflow step, replace the source-compiling `cargo install wasm-opt
--locked` command with an apt-based installation of the `binaryen` package,
which provides the existing `wasm-opt` executable. Leave the subsequent
`wasm-opt` invocation unchanged.

1-7: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Add a concurrency group to cancel superseded workflow runs.

Without a concurrency group, rapid pushes to main or develop will queue multiple redundant runs, wasting CI minutes. Add a concurrency block to cancel in-progress runs when a new commit is pushed.

♻️ Suggested addition
 on:
   pull_request:
     branches: [ "main", "develop" ]

+concurrency:
+  group: ${{ github.workflow }}-${{ github.ref }}
+  cancel-in-progress: true
+
 env:
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/ci.yml around lines 1 - 7, Add a top-level concurrency
configuration to the workflow alongside name and on, using a group keyed to the
workflow and relevant ref, and enable cancellation of in-progress runs so newer
commits supersede older runs.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/ci.yml:
- Around line 22-23: Update both actions/checkout@v4 steps in the CI workflow,
including the checkout in the deploy job, to set persist-credentials to false.
Keep the existing checkout behavior unchanged apart from disabling credential
persistence.

---

Outside diff comments:
In @.github/workflows/ci.yml:
- Around line 1-106: Add a top-level permissions block near the workflow
metadata, granting only contents: read. Leave the existing jobs and steps
unchanged so checkout and artifact upload continue using the minimum required
token access.

---

Nitpick comments:
In @.github/workflows/ci.yml:
- Around line 90-92: Apply RUSTFLAGS="-C target-cpu=mvp" to the WASM build
command in the build-and-test job, matching the existing deploy job
configuration. Keep both jobs’ WASM artifacts built with the same compiler
flags.
- Around line 88-96: In the “Build and optimize WASM” workflow step, replace the
source-compiling `cargo install wasm-opt --locked` command with an apt-based
installation of the `binaryen` package, which provides the existing `wasm-opt`
executable. Leave the subsequent `wasm-opt` invocation unchanged.
- Around line 1-7: Add a top-level concurrency configuration to the workflow
alongside name and on, using a group keyed to the workflow and relevant ref, and
enable cancellation of in-progress runs so newer commits supersede older runs.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 332993e7-6a2c-4ba3-aa5d-d1d456e6b150

📥 Commits

Reviewing files that changed from the base of the PR and between da2c664 and 399913a.

📒 Files selected for processing (2)
  • .github/workflows/ci.yml
  • .github/workflows/rust.yml
💤 Files with no reviewable changes (1)
  • .github/workflows/rust.yml

Comment thread .github/workflows/rust.yml
Security hardening per CodeRabbit review. Prevents GITHUB_TOKEN
from being persisted in .git/config, reducing credential exposure
risk in a workflow that handles deployment secrets.
@Queenode

Copy link
Copy Markdown
Contributor

@abimbolaalabi , thank you for your contribution, all check passed, please resolve conflict for me to be able to merge

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 3

🧹 Nitpick comments (3)
.github/workflows/rust.yml (3)

44-58: 🗄️ Data Integrity & Integration | 🔵 Trivial | ⚡ Quick win

Build-and-test's uploaded WASM artifact differs from the one actually deployed.

This job's WASM build (line 51) doesn't set RUSTFLAGS="-C target-cpu=mvp", but the deploy job (lines 94-96) rebuilds with that flag before optimizing and deploying. The artifact uploaded here for inspection/consumption is therefore not byte-identical to what reaches testnet, which can be misleading for anyone relying on the uploaded artifact as "the tested build."

Align the flags (e.g. add RUSTFLAGS="-C target-cpu=mvp" here too) so the tested/uploaded artifact matches what's deployed.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/rust.yml around lines 44 - 58, Update the “Build
WebAssembly (release)” step to set RUSTFLAGS to “-C target-cpu=mvp”, matching
the deploy job’s WASM build configuration so the uploaded
kolo_savings_group.wasm artifact is identical to the deployed build.

92-101: 🚀 Performance & Scalability | 🔵 Trivial | ⚡ Quick win

Pin wasm-opt version for reproducible, faster builds.

cargo install wasm-opt --locked installs whatever is currently the latest published version and compiles Binaryen from source with no caching between runs, which is both slow and non-deterministic across CI runs (a newer wasm-opt could behave differently or take a while to build each time). Pin a specific version and consider caching ~/.cargo/bin or the wasm-opt build artifacts.

♻️ Suggested fix
-          cargo install wasm-opt --locked
+          cargo install wasm-opt --version <pinned-version> --locked
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/rust.yml around lines 92 - 101, Update the “Build and
optimize WASM” workflow step to install a specific pinned version of wasm-opt
instead of the unversioned package, preserving the existing locked installation
and optimization flow. Add CI caching for the wasm-opt executable or its build
artifacts if the workflow’s established caching mechanism supports it.

84-90: 🔒 Security & Privacy | 🔵 Trivial | ⚡ Quick win

Harden the Stellar CLI download: fail-fast and verify integrity.

curl -sSL ... | tar -xz has no -f flag, so an HTTP error page (e.g. 404 if the release/asset naming changes) could be silently piped into tar producing a confusing failure instead of a clear one. There's also no checksum/signature verification of the downloaded release binary before it's placed on $PATH and executed to deploy funds/contracts.

🔒 Suggested fix
-          curl -sSL https://github.com/stellar/soroban-tools/releases/download/v21.2.0/soroban-cli-21.2.0-x86_64-unknown-linux-gnu.tar.gz | tar -xz
+          curl -fsSL https://github.com/stellar/soroban-tools/releases/download/v21.2.0/soroban-cli-21.2.0-x86_64-unknown-linux-gnu.tar.gz | tar -xz
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/rust.yml around lines 84 - 90, Update the “Install Stellar
CLI” workflow step to download the release with curl fail-fast options, then
verify the downloaded archive or binary against the release’s published
checksum/signature before extracting and moving soroban into $HOME/.local/bin.
Only add the executable to GITHUB_PATH and run soroban --version after
verification succeeds.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/rust.yml:
- Around line 102-109: Update the “Deploy contract to testnet” step so the
deployer secret is imported into a local Soroban identity using soroban keys add
with secret input supplied via stdin or the environment, then invoke soroban
contract deploy with the identity alias through --source rather than passing the
raw key via --source-account.
- Around line 1-13: Add a top-level permissions block to the workflow granting
only contents: read for both jobs. If the deploy job requires repository write
access, override permissions narrowly within that job; otherwise keep the
read-only setting.
- Around line 84-90: Update the “Install Stellar CLI” workflow step to use a
valid Stellar CLI release and matching release asset URL instead of the
nonexistent soroban-tools v21.2.0 asset. Keep the extraction, installation path,
GITHUB_PATH update, and version check unchanged.

---

Nitpick comments:
In @.github/workflows/rust.yml:
- Around line 44-58: Update the “Build WebAssembly (release)” step to set
RUSTFLAGS to “-C target-cpu=mvp”, matching the deploy job’s WASM build
configuration so the uploaded kolo_savings_group.wasm artifact is identical to
the deployed build.
- Around line 92-101: Update the “Build and optimize WASM” workflow step to
install a specific pinned version of wasm-opt instead of the unversioned
package, preserving the existing locked installation and optimization flow. Add
CI caching for the wasm-opt executable or its build artifacts if the workflow’s
established caching mechanism supports it.
- Around line 84-90: Update the “Install Stellar CLI” workflow step to download
the release with curl fail-fast options, then verify the downloaded archive or
binary against the release’s published checksum/signature before extracting and
moving soroban into $HOME/.local/bin. Only add the executable to GITHUB_PATH and
run soroban --version after verification succeeds.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: 92366b93-c1b6-4d31-9096-f69647a062eb

📥 Commits

Reviewing files that changed from the base of the PR and between f391cf6 and 0ac43dd.

📒 Files selected for processing (1)
  • .github/workflows/rust.yml

Comment thread .github/workflows/rust.yml
Comment thread .github/workflows/rust.yml Outdated
Comment on lines +102 to +109
- name: Deploy contract to testnet
env:
STELLAR_SOURCE_ACCOUNT: ${{ secrets.STELLAR_DEPLOYER_KEY }}
run: |
soroban contract deploy \
--wasm target/wasm32-unknown-unknown/release/kolo_savings_group.optimized.wasm \
--source-account "$STELLAR_SOURCE_ACCOUNT" \
--network testnet

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

🔒 Security & Privacy | 🟠 Major | ⚡ Quick win

Secret key is passed as a literal CLI argument.

--source-account "$STELLAR_SOURCE_ACCOUNT" expands the raw deployer secret key directly into the soroban process's command-line arguments, which are visible to any other process on the runner via /proc/<pid>/cmdline or ps for the process lifetime. Prefer importing the key into a local identity (soroban keys add ... --secret-key, reading the secret from stdin/env inside that command) and referencing the identity alias with --source instead of interpolating the raw secret onto the command line.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/rust.yml around lines 102 - 109, Update the “Deploy
contract to testnet” step so the deployer secret is imported into a local
Soroban identity using soroban keys add with secret input supplied via stdin or
the environment, then invoke soroban contract deploy with the identity alias
through --source rather than passing the raw key via --source-account.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🧹 Nitpick comments (1)
.github/workflows/rust.yml (1)

93-94: 🩺 Stability & Availability | 🔵 Trivial | ⚡ Quick win

Pin the Stellar CLI version used for deployment.

cargo install stellar-cli --locked has no package-version constraint, so it does not enforce the stated v21.2.0 requirement. Cargo supports --version/@version, while Stellar documents the unversioned form as installing the latest source version. (doc.rust-lang.org)

Suggested fix
- cargo install stellar-cli --locked
+ cargo install stellar-cli --version <verified-version> --locked
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In @.github/workflows/rust.yml around lines 93 - 94, Update the Stellar CLI
installation command in the workflow to explicitly pin version 21.2.0 using
Cargo’s supported package-version syntax, while preserving the existing --locked
behavior and subsequent stellar --version check.

Source: MCP tools

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In @.github/workflows/rust.yml:
- Line 3: Update the workflow-level permissions declaration to valid YAML by
representing contents read access as a nested permissions mapping, preserving
the existing read-only access.

---

Nitpick comments:
In @.github/workflows/rust.yml:
- Around line 93-94: Update the Stellar CLI installation command in the workflow
to explicitly pin version 21.2.0 using Cargo’s supported package-version syntax,
while preserving the existing --locked behavior and subsequent stellar --version
check.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro Plus

Run ID: fd88be85-1e01-438c-9597-a2868e13a759

📥 Commits

Reviewing files that changed from the base of the PR and between d504b48 and 7a202e7.

📒 Files selected for processing (1)
  • .github/workflows/rust.yml

Comment thread .github/workflows/rust.yml Outdated
@abimbolaalabi

Copy link
Copy Markdown
Contributor Author

@Queenode it has been resolved accordingly. Please review!

@Queenode

Copy link
Copy Markdown
Contributor

Thank you for your contribution @abimbolaalabi

@Queenode
Queenode merged commit 38783e7 into Kolo-Org:main Jul 21, 2026
2 of 3 checks passed
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

(CI/CD) pipeline integration

2 participants